#include <iostream>
#include <fstream>
#include <string>
#include "find_yellow_rect.hpp"
#include "rapidjson/document.h"

void read_file_content(std::string str_json_file_path, std::string &str_content)
{
        std::ifstream file(str_json_file_path.c_str());
        if (file.is_open()) {
                std::stringstream buffer;
                buffer << file.rdbuf();
                str_content = buffer.str();
        }
        else {
                str_content = std::string();
        }
}

bool read_param(std::string &str_json_file_path,
        std::string &str_video_path,
        std::string &str_save_folder)
{
        std::string str_json_file_content;
        read_file_content(str_json_file_path, str_json_file_content);
        if (str_json_file_content.empty()) {
                std::cerr << "json file does not exist or is empty, file path: "
                        << str_json_file_path << std::endl;
                return false;
        }

        rapidjson::Document document;
        document.Parse(str_json_file_content.c_str());
        if (document.HasParseError()) {
                std::cerr << "json file has parse error, file path: " 
                        << str_json_file_path << std::endl;
                return false;
        }

        rapidjson::Value::ConstMemberIterator itr =
                document.FindMember("VideoPath");
        if (itr != document.MemberEnd()) {
                str_video_path = std::string(itr->value.GetString());
        }
        else {
                str_video_path = std::string();
        }

        itr = document.FindMember("SaveFolder");
        if (itr != document.MemberEnd()) {
                str_save_folder = std::string(itr->value.GetString());
        }
        else {
                str_save_folder = std::string();
        }

        return (!str_video_path.empty()) && (!str_save_folder.empty());
}


int main(int argc, char **argv)
{
        if (argc < 2) {
                std::cerr << argv[0] << " json_file_path" << std::endl;
                return 1;
        }
        std::string str_json_file_path(argv[1]);
        std::cout << "json file path: " << str_json_file_path << std::endl;

        std::string str_video_path, str_save_folder;
        if (!read_param(str_json_file_path, str_video_path, str_save_folder)) {
                std::cerr << "read json file failed." << std::endl;
                return 1;
        }

        cv::VideoCapture video;
        if (!video.open(str_video_path)) {
                std::cerr << "can not open the video: " 
                        << str_video_path << std::endl;
                system("pause");
                return 1;
        }
        cv::namedWindow("yellow_rect_detector");
        cv::Mat frame;
        char szpath[200]; memset(szpath, 0, sizeof(szpath));
        int count = 1;
        while (true) {
                video >> frame;
                if (frame.empty()) break;
                cv::Rect yellow_rect;
                if (find_yellow_rect(frame, yellow_rect)) {
                        std::cout << "find yellow rect." << std::endl;
                        cv::Mat &yellow_rect_img = frame(yellow_rect);
                        sprintf_s(szpath, sizeof(szpath), "%s\\%05d.png",
                                str_save_folder.c_str(), count);
                        cv::imwrite(szpath, yellow_rect_img);
                        count += 1;
                }
                cv::imshow("yellow_rect_detector", frame);
                if (cv::waitKey(3) == 27) break;
        }
        cv::destroyWindow("yellow_rect_detector");
        return 0;
}